package core;

public class PersonAccount {

	// asset = floating_money + goods_num*price
	private float m_asset;

	// positive means have bought some goods, negative means have sold some
	// goods.
	private float m_goods_quantity = 0;

	// floating money
	private float m_floating_money = 0;

	// remaining available money that can be used to invest
	private float m_available_money = 0;

	private float m_max_asset = 0;

	private float m_min_asset = 0;

	private float m_buy_price;
	private float m_sell_price;

	public PersonAccount(float money) {
		m_asset = money;
		m_floating_money = money;
		m_available_money = money;
		m_max_asset = money;
		m_min_asset = money;
	}

	public void updateGoods(float buy_price, float sell_price) {
		m_buy_price = buy_price;
		m_sell_price = sell_price;
		updateAsset();
	}

	public boolean buy(float num) {
		// buy the over-sold goods first
		float cover_quant = 0.0f;
		if (m_goods_quantity < 0) {
			cover_quant = -m_goods_quantity;
		}

		if (m_available_money > m_buy_price * (num - cover_quant)) {
			addGold(num);
			addMoney(-m_buy_price * num);

			updateAsset();

			System.out.println("Buy Goods Num: " + num + "\tbuy price = " + m_buy_price
							+ "\trate = " + getGoodsRate());
			return true;
		}

		return false;
	}

	public boolean sell(float num) {
		// sell the remaining goods first
		float cover_quant = 0.0f;
		if (m_goods_quantity > 0) {
			cover_quant = m_goods_quantity;
		}

		if (m_available_money > m_buy_price * (num - cover_quant)) {
			addGold(-num);
			addMoney(m_sell_price * num);

			updateAsset();

			System.out.println("Sell Goods Num: " + num + "\tsell price = " + m_sell_price
							+ "\trate = " + getGoodsRate());
			return true;
		}

		return false;
	}

	public float getAsset() {
		return m_asset;
	}

	// available money that can be used to invest
	public float getAvailableMoney() {
		return m_available_money;
	}

	// ��λ����
	public float getGoodsRate() {
		float available_rate = getAvailableMoney() / getAsset();
		float goods_rate = 1 - available_rate;
		return goods_rate;
	}

	public float getGoodsQuantity() {
		return m_goods_quantity;
	}

	public int getBuyNum(float rate) {
		return (int) (rate * getAvailableMoney() / m_buy_price);
	}

	public int getSellNum(float rate) {
		return (int) (rate * getAvailableMoney() / m_sell_price);
	}

	private void updateAsset() {
		if (m_goods_quantity > 0) {
			m_asset = m_floating_money + (m_sell_price * m_goods_quantity);
		} else {
			m_asset = m_floating_money + (m_buy_price * m_goods_quantity);
		}

		updateAvailableMoney();

		if (m_asset > m_max_asset)
			m_max_asset = m_asset;

		if (m_asset < m_min_asset)
			m_min_asset = m_asset;
	}

	private void updateAvailableMoney() {
		m_available_money = m_floating_money;

		if (m_goods_quantity < 0) {
			m_available_money += 2 * m_buy_price * m_goods_quantity;
		}
	}

	public String toAllResults() {
		return "Current Asset\t= " + getAsset() + "\nMax Asset\t= " + m_max_asset
						+ "\nMin Asset\t= " + m_min_asset + "\n available money\t= " + m_asset
						+ "\ngoods\t= " + m_goods_quantity;
	}

	private void addMoney(float money) {
		m_floating_money += money;
	}

	private void addGold(float num) {
		m_goods_quantity += num;
	}

}
